/**
 * 参与相关
 */
import {Toast} from 'vant'
import {getJwtPayloadFunc} from '../script/common'
import {safeRequestFunc} from '../script/service'

// TOKEN数据定义
interface Token {
    accessToken: string,
    refreshToken: string,
}

export default {
    data () {
        return  {
            // 参与信息
            actorInfo: {},
        }
    },
    watch: {
        actorAccessToken: {
            immediate: true,
            async handler (newValue) {
                console.log('[watch@actorAccessToken]#监听AccessToken变化：', newValue)
                if (newValue) {
                    this.ACTOR_ACCESS_TOKEN_UPDATE_FUNC_LIST && this.onCallExecute(this.ACTOR_ACCESS_TOKEN_UPDATE_FUNC_LIST)
                }
            }
        },
    },
    computed: {
        actorAccessToken () {
            let token = this.getTokenFunc()
            if (!token || !token.accessToken) {
                return null
            }
            return token.accessToken
        }
    },
    methods: {
        // region 功能方法 +++++
        /**
         * 授权登陆
         * @param commonToken
         */
        async actorAuthLoginFunc (commonToken: string = ''):Promise<any[]> {
            console.log('[actorAuthLoginFunc]#开始执行++++++++++')
            try {
                // 刷新登陆
                let [refreshLoginError, refreshLoginResult] = await this.actorRefreshLoginFunc()
                console.log('[actorAuthLoginFunc]#刷新登陆', refreshLoginError, refreshLoginResult)
                if (refreshLoginError && refreshLoginError !== 'NotToken') {
                    return Promise.resolve([refreshLoginError, null])
                }
                if (refreshLoginResult) {
                    return Promise.resolve([null, refreshLoginResult])
                }
                // region 授权登陆 +++++
                if (!commonToken) {
                    return Promise.resolve(['NotCommonToken', null])
                }
                // 授权接口
                if (!this.API_ACTOR_AUTH) {
                    return Promise.resolve(['授权登陆接口配置错误', null])
                }
                let [apiError, apiResult] = await this.appRequestFunc({
                    url: this.API_ACTOR_AUTH,
                    method: 'post',
                    data: {
                        main_id: this.MAIN_ID,
                        from_actor_id: this.FROM_ACTOR_ID || 0,
                    },
                    headers: {
                        Authorization: 'bearer ' + commonToken
                    }
                })
                console.log('[actorAuthLoginFunc]#授权登陆信息', apiError, apiResult)
                if (apiError || apiResult.code !== 1) {
                    return Promise.resolve([apiError || apiResult.msg, null])
                }
                // 设置TOKEN
                this.setTokenFunc(apiResult.data.access_token, apiResult.data.refresh_token)
                return Promise.resolve([null, {
                    accessToken: apiResult.data.access_token,
                    refreshToken: apiResult.data.refresh_token
                }])
            } catch (exception) {
                console.log('[actorAuthLoginFunc]#异常', exception)
                return Promise.resolve(['[actorAuthLoginFunc]#异常:' + exception.message, null])
            }
        },
        /**
         * 登陆刷新
         */
        async actorRefreshLoginFunc ():Promise<any[]> {
            console.log('[actorRefreshLoginFunc]#开始执行++++++++++')
            try {
                // 取得本地TOKEN
                let token = this.getTokenFunc()
                console.log('[actorRefreshLoginFunc]#获取TOKEN', token)
                if (token) {
                    // 解析TOKEN
                    let jwtPayload = getJwtPayloadFunc(token.accessToken)
                    console.log('[actorRefreshLoginFunc]#解析TOKEN负载', jwtPayload)
                    if (!jwtPayload) {
                        throw new Error('TOKEN解析失败')
                    }
                    if (jwtPayload.master_id != this.MAIN_ID || jwtPayload.user_type != this.ACTOR_TYPE) {
                        throw new Error('TOKEN数据错误')
                    }
                    // @ts-ignore
                    if ($GP.Util.dayJS().unix() + 30 >= jwtPayload.exp) {
                        console.log('[actorRefreshLoginFunc]#TOKEN过期')
                        if (!this.API_ACTOR_TOKEN) {
                            return Promise.resolve(['刷新接口配置错误', null])
                        }
                        // 刷新TOKEN
                        let [apiError, apiResult] = await this.appRequestFunc({
                            url: this.API_ACTOR_TOKEN,
                            method: 'post',
                            data: {
                                main_id: this.MAIN_ID,
                                refresh_token: token.refreshToken
                            },
                            headers: {
                                Authorization: 'bearer ' + token.accessToken
                            }
                        })
                        console.log('[actorRefreshLoginFunc]#TOKEN刷新', apiError, apiResult)
                        if (apiError || apiResult.code !== 1) {
                            // 刷新失败删除本地存储
                            this.delTokenFunc()
                            return Promise.resolve([apiError || apiResult.msg, null])
                        }
                        // 更新TOKEN
                        token.accessToken = apiResult.data.access_token
                        // 设置TOKEN
                        this.setTokenFunc(token.accessToken)
                    }
                    return Promise.resolve([null, token])
                }
                return Promise.resolve(['NotToken', null])
            } catch (exception) {
                console.log('[actorRefreshLoginFunc]#异常', exception)
                return Promise.resolve(['[actorRefreshLoginFunc]#异常:' + exception.message, null])
            }
        },
        /**
         * 认证绑定
         * @param bindToken
         */
        async actorAuthBindFunc (bindToken = ''):Token|null {
            if (!bindToken) {
                Toast.fail('缺少BindToken参数')
                return null
            }
            let [apiError, apiResult] = await this.appRequestFunc({
                loginAuth: true, // 需要登陆认证
                url: this.API_ACTOR_AUTH_BIND,
                method: 'post',
                data: {
                    main_id: this.MAIN_ID,
                    bind_token: bindToken
                },
            })
            console.log('[actorAuthBindFunc]#请求结果', apiError, apiResult)
            if (apiError || apiResult.code !== 1) {
                Toast.fail(apiError || apiResult.msg)
                return null
            }
            // 设置TOKEN
            return this.setTokenFunc(apiResult.data.access_token)
        },
        /**
         * 获取参与信息
         */
        async actorInfoFunc () {
            let [apiError, apiResult] = await this.appRequestFunc({
                loginAuth: true, // 需要登陆认证
                url: this.API_ACTOR_INFO,
                method: 'post',
                data: {
                    main_id: this.MAIN_ID
                },
            })
            console.log('[actorInfoFunc]#接口返回', apiError, apiResult)
            if (apiError || apiResult.code != 1) {
                Toast.fail(apiError || apiResult.msg)
                return null
            }
            this.actorInfo = apiResult.data
            if (this.DATA_HUB_ACTOR_INFO) {
                this.dataHubSet(this.DATA_HUB_ACTOR_INFO, this.actorInfo)
            }
            return this.actorInfo
        },
        /**
         * 请求处理
         * @param setting
         */
        async appRequestFunc (setting:object = {}) {
            console.log('[appRequestFunc]#请求参数', setting)
            if (!setting?.baseURL) {
                setting.baseURL = this.API_BASE
            }
            // 加载提示
            if (setting?.loadingEnable) {
                Toast.loading({
                    message: setting.loadingMessage || '加载中...',
                    forbidClick: setting.loadingForbidClick || true,
                });
            }
            if (setting?.loginAuth) {
                console.log('[appRequestFunc]#需要登陆认证')
                let [loginAuthError, loginAuthResult] = await this.actorRefreshLoginFunc()
                console.log('[appRequestFunc]#登陆刷新结果', loginAuthError, loginAuthResult)
                if (loginAuthError) {
                    // 取消请求
                    setting.cancelRequest = true
                }
                // 携带TOKEN
                if (loginAuthResult) {
                    console.log('[appRequestFunc]#携带Authorization', loginAuthResult.accessToken)
                    setting.headers = setting.headers || {}
                    setting.headers = {
                        ...setting.headers,
                        ...{
                            Authorization: 'bearer ' + loginAuthResult.accessToken
                        }
                    }
                }
            }
            console.log('[appRequestFunc]#处理后请求参数', setting)
            return await safeRequestFunc(setting)
        },
        // endregion
        // region 认证信息 +++++
        /**
         * 设置TOKEN
         * @param accessToken
         * @param refreshToken
         */
        setTokenFunc (accessToken:string = '', refreshToken:string = ''):Token|null {
            try {
                this.setDataHubTokenFunc(accessToken, refreshToken)
                this.setLocalTokenFunc(accessToken, refreshToken)
                return this.getTokenFunc()
            } catch (exception) {
                console.log('[setTokenFunc]#异常', exception)
                return null
            }
        },
        /**
         * 获取TOKEN
         */
        getTokenFunc ():Token|null {
            try {
                return this.getDataHubTokenFunc() || this.getLocalTokenFunc()
            } catch (exception) {
                console.log('[getTokenFunc]#异常', exception)
                return null
            }
        },
        /**
         * 删除TOKEN
         */
        delTokenFunc ():boolean {
            try {
                this.delDataHubTokenFunc()
                this.delLocalTokenFunc()
                return true
            } catch (exception) {
                console.log('[delTokenFunc]#异常', exception)
                return false
            }
        },
        /**
         * 设置数据总线上的TOKEN
         * @param accessToken
         * @param refreshToken
         */
        setDataHubTokenFunc (accessToken:string = '', refreshToken:string = ''):boolean {
            try {
                if (accessToken) {
                    let accessTokenName = this.getAccessTokenNameFunc()
                    accessTokenName && this.dataHubSet(accessTokenName, accessToken)
                }
                if (refreshToken) {
                    let refreshTokenName = this.getRefreshTokenNameFunc()
                    refreshTokenName && this.dataHubSet(refreshTokenName, refreshToken)
                }
                return true
            } catch (exception) {
                console.log('[setDataHubTokenFunc]#异常', exception)
                return false
            }
        },
        /**
         * 从数据总线获取TOKEN
         */
        getDataHubTokenFunc ():Token|null {
            try {
                let accessTokenName = this.getAccessTokenNameFunc()
                let accessToken = accessTokenName && this.dataHubGet(accessTokenName, null)
                let refreshTokenName = this.getRefreshTokenNameFunc()
                let refreshToken = refreshTokenName && this.dataHubGet(refreshTokenName, null)
                if (accessToken && refreshToken) {
                    return {
                        accessToken,
                        refreshToken
                    }
                }
                return null
            } catch (exception) {
                console.log('[getDataHubTokenFunc]#异常', exception)
                return null
            }
        },
        /**
         * 从数据总线删除TOKEN
         */
        delDataHubTokenFunc ():boolean {
            try {
                let accessTokenName = this.getAccessTokenNameFunc()
                accessTokenName && this.dataHubSet(accessTokenName, '')
                let refreshTokenName = this.getRefreshTokenNameFunc()
                refreshTokenName && this.dataHubSet(refreshTokenName, '')
                return true
            } catch (exception) {
                console.log('[getDataHubTokenFunc]#异常', exception)
                return false
            }
        },
        /**
         * 设置本地存储上的TOKEN
         * @param accessToken
         * @param refreshToken
         */
        setLocalTokenFunc (accessToken:string = '', refreshToken:string = ''):boolean {
            try {
                if (accessToken) {
                    let accessTokenName = this.getAccessTokenNameFunc()
                    accessTokenName && window.localStorage.setItem(accessTokenName, accessToken)
                }
                if (refreshToken) {
                    let refreshTokenName = this.getRefreshTokenNameFunc()
                    refreshTokenName && window.localStorage.setItem(refreshTokenName, refreshToken)
                }
                return true
            } catch (exception) {
                console.log('[setLocalTokenFunc]#异常', exception)
                return false
            }
        },
        /**
         * 从本地存储获取TOKEN
         */
        getLocalTokenFunc ():Token|null {
            try {
                let accessTokenName = this.getAccessTokenNameFunc()
                let accessToken = accessTokenName && window.localStorage.getItem(accessTokenName)
                let refreshTokenName = this.getRefreshTokenNameFunc()
                let refreshToken = refreshTokenName && window.localStorage.getItem(refreshTokenName)
                if (accessToken && refreshToken) {
                    return {
                        accessToken,
                        refreshToken
                    }
                }
                return null
            } catch (exception) {
                console.log('[getLocalTokenFunc]#异常', exception)
                return null
            }
        },
        /**
         * 从本地存储删除TOKEN
         */
        delLocalTokenFunc ():boolean {
            try {
                let accessTokenName = this.getAccessTokenNameFunc()
                accessTokenName && window.localStorage.removeItem(accessTokenName)
                let refreshTokenName = this.getRefreshTokenNameFunc()
                refreshTokenName && window.localStorage.removeItem(refreshTokenName)
                return true
            } catch (exception) {
                console.log('[getLocalTokenFunc]#异常', exception)
                return false
            }
        },
        /**
         * 获取AccessToken名称
         */
        getAccessTokenNameFunc ():string {
            return this.APP_NAME + '_' + this.STORE_ACCESS_TOKEN_NAME + '_' + this.MAIN_ID
        },
        /**
         * 获取RefreshToken名称
         * @returns {string}
         */
        getRefreshTokenNameFunc ():string {
            return this.APP_NAME + '_' + this.STORE_REFRESH_TOKEN_NAME + '_' + this.MAIN_ID
        },
        // endregion
        // region 调用方法 +++++
        // 参与授权登陆钩子
        async callActorAuthLoginFunc (funcParam = [], callParam = {}, resultList = []) {
            console.log('[callActorAuthLoginFunc]#参数配置：', funcParam, callParam, resultList)
            let token = ''
            if (callParam[this.APP_NAME + '@actorAuthLoginFunc']) {
                token = callParam[this.APP_NAME + '@actorAuthLoginFunc']
            } else if (callParam['accessToken']) {
                token = callParam['accessToken']
            } else {
                token = funcParam[0]
            }
            console.log('[callActorAuthLoginFunc]#授权登陆TOKEN：', token)
            if (!token) {
                return Promise.resolve(['缺少授权TOKEN参数', null])
            }
            return Promise.resolve(await this.actorAuthLoginFunc(token))
        },
        // 参与授权绑定钩子
        async callActorAuthBindFunc (funcParam = [], callParam = {}, resultList = []) {
            console.log('[callActorAuthBindFunc]#参数配置：', funcParam, callParam, resultList)
            let token = ''
            if (callParam[this.APP_NAME + '@actorAuthBindFunc']) {
                token = callParam[this.APP_NAME + '@actorAuthBindFunc']
            } else if (callParam['accessToken']) {
                token = callParam['accessToken']
            } else {
                token = funcParam[0]
            }
            if (!token) {
                return Promise.resolve(['缺少绑定TOKEN参数', null])
            }
            return Promise.resolve(await this.actorAuthBindFunc(token))
        },
        // 获取参与信息钩子
        async callActorInfoFunc (funcParam = [], callParam = {}, resultList = []) {
            console.log('[callActorInfoFunc]#参数配置：', funcParam, callParam, resultList)
            return Promise.resolve(await this.actorInfoFunc())
        },
        // endregion
    },
    editorMethods: {
        // 角色认证登陆钩子
        callActorAuthLoginFunc: {
            label: '调用-活动参与授权登陆',
            params: [{
                label: '公共TOKEN',
                desc: '用于授权登陆的CommonToken，一般为其它第三方登陆用户Token',
                type: 'string',
                default: '',
            }]
        },
        // 角色认证绑定钩子
        callActorAuthBindFunc: {
            label: '调用-活动参与授权绑定',
            params: [{
                label: '绑定TOKEN',
                desc: '用于授权绑定的BindToken，一般为其它第三方登陆用户Token',
                type: 'string',
                default: '',
            }]
        },
        // 用户信息
        callActorInfoFunc: {
            label: '调用-获取参与用户信息',
        },
    },
}
